package com.zdkj.subway.stm.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zdkj.admin.api.entity.SysDictItem;
import com.zdkj.common.core.constant.CommonConstants;
import com.zdkj.common.core.constant.SecurityConstants;
import com.zdkj.common.core.exceltools.MultipartFileToFile;
import com.zdkj.common.core.util.R;
import com.zdkj.common.log.annotation.SysLog;
import com.zdkj.common.security.annotation.Inner;
import com.zdkj.common.security.service.PigxUser;
import com.zdkj.common.security.util.SecurityUtils;
import com.zdkj.subway.stm.constant.StmConstans;
import com.zdkj.subway.stm.dto.in.*;
import com.zdkj.subway.stm.dvo.SwStTicketHandAndDetailExcelDvo;
import com.zdkj.subway.stm.dvo.SwStTicketHandDvo;
import com.zdkj.subway.stm.dvo.SwStTicketHandRecoveryDvo;
import com.zdkj.subway.stm.entity.*;
import com.zdkj.subway.stm.enums.TicketInHandEnum;
import com.zdkj.subway.stm.fegin.SubwayStService;
import com.zdkj.subway.stm.fegin.SystemUserService;
import com.zdkj.subway.stm.mapper.SwParamLineMapper;
import com.zdkj.subway.stm.mapper.SwParamStationMapper;
import com.zdkj.subway.stm.mapper.SwStTicketHandMapper;
import com.zdkj.subway.stm.service.SwPmTicketCardTypeParamService;
import com.zdkj.subway.stm.service.SwPmTicketCardTypeService;
import com.zdkj.subway.stm.service.SwStTicketHandDetailService;
import com.zdkj.subway.stm.service.SwStTicketHandService;
import com.zdkj.subway.stm.util.DateUtilStm;
import com.zdkj.subway.stm.util.LocalDateConverter;
import com.zdkj.subway.stm.util.LocalDateTimeConverter;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 车票上交(回收)主表
 *
 * @author cuilei
 * @date 2020-05-26 15:03:29
 */
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/swsttickethand")
@Api(value = "swsttickethand", tags = "车票上交主表管理")
public class SwStTicketHandController {
    private static final Logger LOGGER = LoggerFactory.getLogger(SwStTicketHand.class);
    private final SwStTicketHandService swStTicketHandService;
    private final SwStTicketHandDetailService swStTicketHandDetailService;
    private final SubwayStService subwayStService;

    private final SystemUserService systemUserService;
    @Resource
    private SwParamLineMapper swParamLineMapper;
    @Resource
    private SwParamStationMapper swParamStationMapper;
    @Resource
    private final SwPmTicketCardTypeService swPmTicketCardTypeService;
    @Resource
    private final SwPmTicketCardTypeParamService swPmTicketCardTypeParamService;
    @Resource
    SwStTicketHandMapper swStTicketHandMapper;
    /**
     * 分页查询
     *
     * @param page           分页对象
     * @param swStTicketHand 车票上交主表
     * @return
     */
    @ApiOperation(value = "分页查询", notes = "分页查询")
    @GetMapping({"/page", "/line/page"})
    public R getSwStTicketHandPage(Page page, SwStTicketHand swStTicketHand) {
        PigxUser user = SecurityUtils.getUser();
        List<String> dateConditionhs = new ArrayList<>();
        List<String> dateConditionhs2 = new ArrayList<>();
        List<String> dateConditionhs3 = new ArrayList<>();
        //markId标识：1:车票上交 2:车票回收
        if(swStTicketHand.getMarkId()==1){
            dateConditionhs = swStTicketHand.getDates1();
        }else{
            dateConditionhs2 = swStTicketHand.getDates1();
            if(CollectionUtil.isNotEmpty(swStTicketHand.getDates2())){
                if(swStTicketHand.getDates2().get(0)!=null&&!"".equals(swStTicketHand.getDates2().get(0))){
                    dateConditionhs3 = swStTicketHand.getDates2();
                }
            }
        }
        QueryWrapper<SwStTicketHand> queryWrapper = Wrappers.query(swStTicketHand);
        queryWrapper.orderByDesc("-HAND_STATUS","RECEIVE_TIME","HAND_TIME");
        if (ObjectUtil.isNotEmpty(dateConditionhs)) {
            queryWrapper.lambda().apply("DATE_FORMAT(HAND_TIME,'%Y-%m-%d') between DATE_FORMAT('"+dateConditionhs.get(0)+"','%Y-%m-%d') and DATE_FORMAT('"+dateConditionhs.get(1)+"','%Y-%m-%d')");
        }
        if (ObjectUtil.isNotEmpty(dateConditionhs2)) {
            queryWrapper.lambda().apply("DATE_FORMAT(RECEIVE_TIME,'%Y-%m-%d') between DATE_FORMAT('"+dateConditionhs2.get(0)+"','%Y-%m-%d') and DATE_FORMAT('"+dateConditionhs2.get(1)+"','%Y-%m-%d')");
        }
        if (ObjectUtil.isNotEmpty(dateConditionhs3)) {
            queryWrapper.lambda().apply("DATE_FORMAT(HAND_TIME,'%Y-%m-%d') between DATE_FORMAT('"+dateConditionhs3.get(0)+"','%Y-%m-%d') and DATE_FORMAT('"+dateConditionhs3.get(1)+"','%Y-%m-%d')");
        }
        if(!user.getBelongToLine()){
            queryWrapper.lambda().eq(SwStTicketHand::getLineCode,user.getLineCode());
            queryWrapper.lambda().eq(SwStTicketHand::getStationCode,user.getStationCode());
            queryWrapper.lambda().eq(SwStTicketHand::getNoticeStatus, CommonConstants.INFORMED);
            queryWrapper.lambda().eq(SwStTicketHand::getNoticeConfirm,CommonConstants.CONFIRM);
            return R.ok(swStTicketHandService.page(page,queryWrapper));
        }else{
            queryWrapper.lambda().eq(SwStTicketHand::getSubmitStatus,CommonConstants.SUBMIT);
            return R.ok(swStTicketHandService.page(page,queryWrapper));
        }
        /*LambdaQueryWrapper<SwStTicketHand> queryWrapper = Wrappers.query(swStTicketHand).lambda();
        if (ObjectUtil.isNotEmpty(dateConditionhs)) {
            queryWrapper.between(true,SwStTicketHand::getReceiveTime, dateConditionhs.get(0), dateConditionhs.get(1));
        }
        if(!user.getBelongToLine()){
            queryWrapper.eq(SwStTicketHand::getStationCode,user.getStationCode());
            queryWrapper.eq(SwStTicketHand::getNoticeStatus, CommonConstants.INFORMED);
            queryWrapper.eq(SwStTicketHand::getNoticeConfirm,CommonConstants.CONFIRM);
            return R.ok(swStTicketHandService.page(page,queryWrapper));
        }else{
            queryWrapper.eq(SwStTicketHand::getSubmitStatus,CommonConstants.SUBMIT);
            return R.ok(swStTicketHandService.page(page,queryWrapper));
        }*/
    }

    /**
     * 通过id查询车票上交主表
     *
     * @param id id
     * @return R
     */
    @ApiOperation(value = "通过id查询", notes = "通过id查询")
    @GetMapping({"/{id}", "/line/{id}"})
    public R getById(@PathVariable("id") Integer id) {
        return R.ok(swStTicketHandService.getById(id));
    }

    /**
     * 通过id查询车票上交主表及明细
     *
     * @param id id
     * @return R
     */
    @ApiOperation(value = "通过id查询车票上交主表及明细", notes = "通过id查询车票上交主表及明细")
    @GetMapping({"/getDetailById/{id}", "/line/getDetailById/{id}"})
    public R getDetailById(@PathVariable("id") Integer id) {
        return R.ok(swStTicketHandService.getDetailById(id));
    }

    /**
     * 车站新增车票上交及明细
     *
     * @param swStTicketHandInput 车站车票上交主表及明细
     * @return R
     */
    @ApiOperation(value = "车站新增车票上交及明细", notes = "车站新增车票上交及明细")
    @SysLog("车站新增车票上交及明细")
    @PostMapping()
    @PreAuthorize("@pms.hasPermission('stm_sw_st_ticket_hand_add')")
    public R stationSave(@RequestBody SwStTicketHandInputDTO swStTicketHandInput) {
        return R.ok(swStTicketHandService.savePrimaryAndDetails(swStTicketHandInput));
    }

    /**
     * 线网新增车票回收及明细
     *
     * @param swStTicketRecovery
     * @return
     */
    @ApiOperation(value = "线网新增车票回收及明细", notes = "线网新增车票回收及明细")
    @SysLog("线网新增车票回收及明细")
    @PostMapping("/line")
    public R lineSave(@RequestBody SwStTicketRecoveryDTO swStTicketRecovery) {
        return R.ok(swStTicketHandService.savePrimaryAndDetails(swStTicketRecovery));
    }

    /**
     * 线网车票回收通知(线网发送通知到车站)
     *
     * @param listIds
     * @return
     */
    @ApiOperation(value = "线网车票回收通知", notes = "线网车票回收通知")
    @SysLog("线网车票回收通知")
    @PostMapping("/line/inform")
    @PreAuthorize("@pms.hasPermission('stm_sw_st_ticket_hand_inform')")
    @Transactional
    public R inform(@RequestBody List<Integer> listIds) {
        List<SwTkTemporaryDistributionPlanNoticeDTO> informList = new ArrayList<>();
        ArrayList<SwStTicketHandInputDTO> objects = new ArrayList<>();
        List<SwStTicketHand> informUpdateList = new ArrayList<>();
        listIds.forEach(item -> {
            SwStTicketHand informUpdateItem = swStTicketHandService.getById(item);
            //先添加通知表数据
            SwTkTemporaryDistributionPlanNoticeDTO informItem = new SwTkTemporaryDistributionPlanNoticeDTO();
            informItem.setRefId(informUpdateItem.getId());
            informItem.setLineCode(informUpdateItem.getLineCode());
            informItem.setStationCode(informUpdateItem.getStationCode());
            informItem.setDistributionNumber(informUpdateItem.getReceiveCount());
            informItem.setDistributionPersonName(informUpdateItem.getReceivePersonName());
            informItem.setDistributionPersonCode(informUpdateItem.getReceivePersonCode());
            informItem.setDistributionPersonTwoName(informUpdateItem.getReceivePersonTwoName());
            informItem.setDistributionPersonTwoCode(informUpdateItem.getReceivePersonTwoCode());
            informItem.setDistributionTime(informUpdateItem.getReceiveTime());
            informItem.setDistributionType(TicketInHandEnum.RECYCLE.getCode());
            informList.add(informItem);

            //再更改通知状态
            informUpdateItem.setNoticeStatus(CommonConstants.INFORMED);
            informUpdateList.add(informUpdateItem);
        });
        subwayStService.temporaryDistributionPlanBatchNotice(SecurityConstants.FROM_IN,informList);
        return R.ok(swStTicketHandService.updateBatchById(informUpdateList));
    }

    /**
     * 车站修改上交主表及明细
     *
     * @param swStTicketHandEdit 修改车票上交主表及明细
     * @return R
     */
    @ApiOperation(value = "车站修改上交主表及明细", notes = "车站修改上交主表及明细")
    @SysLog("车站修改上交主表及明细")
    @PutMapping
    @PreAuthorize("@pms.hasPermission('stm_sw_st_ticket_hand_edit')")
    public R updateStationById(@RequestBody SwStTicketHandEditDTO swStTicketHandEdit) {
        SwStTicketHand updateObj = new SwStTicketHand();
        BeanUtils.copyProperties(swStTicketHandEdit, updateObj);
        List<SwStTicketHandDetail> swStTicketHandDetails = swStTicketHandEdit.getSwStTicketHandDetails();
        //车站的编辑操作，需重新计算上交数量
        int totalHandCount = swStTicketHandDetails
                .stream().mapToInt(SwStTicketHandDetail::getHandCount).sum();
        updateObj.setHandCount(totalHandCount);
        swStTicketHandService.updateById(updateObj);
        //先移除 再新增
        swStTicketHandDetailService.remove(Wrappers.<SwStTicketHandDetail>lambdaQuery()
                .eq(SwStTicketHandDetail::getRefId,updateObj.getId()).eq(SwStTicketHandDetail::getDelFlag,"0"));
        swStTicketHandDetails.forEach(item -> item.setRefId(updateObj.getId()));
        return R.ok(swStTicketHandDetailService.saveBatch(swStTicketHandDetails));
    }


    /**
     * 线网修改上交主表及明细
     *
     * @param swStTicketHandEdit 修改车票上交主表及明细
     * @return R
     */
    @ApiOperation(value = "线网修改上交主表及明细", notes = "线网修改上交主表及明细")
    @SysLog("线网修改上交主表及明细")
    @PutMapping("/line")
    @PreAuthorize("@pms.hasPermission('stm_sw_st_ticket_hand_edit')")
    public R updateLineById(@RequestBody SwStTicketHandEditDTO swStTicketHandEdit) {
        SwStTicketHand updateObj = new SwStTicketHand();
        BeanUtils.copyProperties(swStTicketHandEdit, updateObj);
        //线网的编辑操作，需重新计算回收数量
        int totalReceiveCount = swStTicketHandEdit.getSwStTicketHandDetails()
                .stream().mapToInt(SwStTicketHandDetail::getReceiveCount).sum();
        updateObj.setReceiveCount(totalReceiveCount);
        swStTicketHandService.updateById(updateObj);
        return R.ok(swStTicketHandDetailService.updateBatchById(swStTicketHandEdit
                .getSwStTicketHandDetails()));
    }

    /**
     * 线网车票回收确认并反馈
     *
     * @param swStTicketHand
     * @return
     */
    @ApiOperation(value = "线网车票回收确认并反馈", notes = "车票回收确认包括 线网添加数据和车站提交")
    @SysLog("线网车票回收确认并反馈")
    @PostMapping("/line/confirmOrFeedBack")
    public R confirmOrFeedback(@RequestBody SwStTicketHandLineEditDTO swStTicketHand) {
        SwStTicketHand confirm = new SwStTicketHand();
        BeanUtils.copyProperties(swStTicketHand, confirm);
        if (StringUtils.isNotBlank(swStTicketHand.getFeedback())) {
            confirm.setHandStatus(TicketInHandEnum.FEEDBACK.getCode());
        } else {
            confirm.setHandStatus(TicketInHandEnum.CONFIRM.getCode());
            //todo 调用线网车票入库接口进行车票入库
        }
        //更新子表数量
        List<SwStTicketHandDetailLineEditDTO> listDetail = swStTicketHand.getSwStTicketHandDetails();
        int sumDiff = 0;
        for (SwStTicketHandDetailLineEditDTO item : listDetail){
            SwStTicketHandDetail swStTicketHandDetail = swStTicketHandDetailService.getById(item.getId());
            BeanUtils.copyProperties(item, swStTicketHandDetail);
            swStTicketHandDetailService.updateById(swStTicketHandDetail);
            sumDiff += swStTicketHandDetail.getDifferenceCount()==null?0:swStTicketHandDetail.getDifferenceCount();
        }
        confirm.setDifferenceCount(sumDiff);
        /*listDetail.forEach(item -> {
            SwStTicketHandDetail swStTicketHandDetail = swStTicketHandDetailService.getById(item.getId());
            BeanUtils.copyProperties(item, swStTicketHandDetail);
            swStTicketHandDetailService.updateById(swStTicketHandDetail);
        });*/

        return R.ok(swStTicketHandService.updateById(confirm));
    }

    /**
     * 车站确认线网车票回收通知，仅供线网临时配收计划模块内部调用
     *
     * @param idList
     * @return
     */
    @Inner
    @ApiOperation(value = "车站确认线网车票回收通知", notes = "车站确认线网车票回收通知")
    //@SysLog("车站确认线网车票回收通知")
    @PostMapping("/noticeConfirm")
    public R noticeConfirm(@RequestBody List<Integer> idList) {
        List<SwStTicketHand> noticeConfirmList = new ArrayList<>();
        idList.forEach(id -> {
            SwStTicketHand noticeConfirmItem = new SwStTicketHand();
            noticeConfirmItem.setId(id);
            noticeConfirmItem.setSubmitStatus(CommonConstants.UN_SUBMIT);
            noticeConfirmItem.setNoticeConfirm(CommonConstants.CONFIRM);
            noticeConfirmList.add(noticeConfirmItem);
        });
        return R.ok(swStTicketHandService.updateBatchById(noticeConfirmList));
    }

    /**
     * 通过id删除车票上交主表
     *
     * @param id id
     * @return R
     */
    @ApiOperation(value = "通过id删除车票上交主表", notes = "通过id删除车票上交主表")
    @SysLog("通过id删除车票上交主表")
    @DeleteMapping("/{id}")
    @PreAuthorize("@pms.hasPermission('stm_sw_st_ticket_hand_del')")
    public R removeById(@PathVariable Integer id) {
        return R.ok(swStTicketHandService.removeById(id));
    }

    /**
     * 车站批量删除车票上交
     *
     * @param idList
     * @return
     */
    @ApiOperation(value = "车站批量删除车票上交", notes = "车站批量删除车票上交")
    @SysLog("车站批量删除车票上交")
    @PostMapping("/batchDelete")
    public R batchDelete(@RequestBody List<Integer> idList) {
        List<Integer> deleteList = new ArrayList<>();
        idList.forEach(id -> {
            SwStTicketHand deleteItem = swStTicketHandService.getById(id);
            if (CommonConstants.SUBMIT.equals(deleteItem.getSubmitStatus())
                    || TicketInHandEnum.LINE_ADD.getCode().equals(deleteItem.getDataSource())) {
                log.info("已提交或线网通知数据不能删除！");
            } else {
                deleteList.add(id);
            }
        });
        return R.ok(swStTicketHandService.removeByIds(deleteList));
    }

    /**
     * 车站批量提交车票上交
     *
     * @return
     */
    @ApiOperation(value = "车站批量提交车票上交", notes = "车站批量提交车票上交")
    @SysLog("车站批量提交车票上交")
    @PostMapping("/submit")
//    @PreAuthorize("@pms.hasPermission('stm_sw_st_ticket_hand_submit')")
    public R submit(@RequestBody List<Integer> idList) {
        List<SwStTicketHand> submitList = new ArrayList<>();
        idList.forEach(id -> {
            SwStTicketHand submitItem = new SwStTicketHand();
            submitItem.setId(id);
            submitItem.setSubmitStatus(CommonConstants.SUBMIT);
            submitList.add(submitItem);
        });
        return R.ok(swStTicketHandService.updateBatchById(submitList));
    }

    /**
     * 车站申诉车票上交差异
     *
     * @param swStTicketHand
     * @return
     */
    @ApiOperation(value = "车站申诉车票上交差异", notes = "车站申诉车票上交差异")
    @SysLog("车站申诉车票上交差异")
    @PostMapping("/complain")
    public R complain(@RequestBody SwStTicketHandStationEditDTO swStTicketHand) {
        SwStTicketHand complain = new SwStTicketHand();
        BeanUtils.copyProperties(swStTicketHand, complain);
        complain.setHandStatus(TicketInHandEnum.CONFIRM.getCode());
        if (StringUtils.isNotBlank(swStTicketHand.getComplain())) {
            //如果填申诉信息就认为是差异申诉，否则是默认接受
            complain.setHandStatus(TicketInHandEnum.COMPLAIN.getCode());
        }
        return R.ok(swStTicketHandService.updateById(complain));
    }

    /**
     * 导出车票上交信息
     *
     * @param ids
     * @param response
     * @throws IOException
     */
    @ApiOperation(value = "导出车票上交信息", notes = "导出车票上交信息")
    @GetMapping("/export")
    @SysLog("导出车票上交信息")
    //@PreAuthorize("@pms.hasPermission('stm_sw_st_ticket_hand_export')")
    public void exportExcel(@RequestParam(value = "ids") List<Integer> ids, HttpServletResponse response) throws IOException {
        List<SwStTicketHandDvo> list = new ArrayList<>();
        List<SwStTicketHand> records;
        PigxUser user = SecurityUtils.getUser();
        if(CollectionUtils.isNotEmpty(ids)){
            records = swStTicketHandMapper.selectBatchIds(ids).stream().sorted(Comparator.comparing(SwStTicketHand::getHandTime).reversed()).collect(Collectors.toList());
        }else{
            QueryWrapper<SwStTicketHand> wrapper = new QueryWrapper<>();
            wrapper.lambda().eq(SwStTicketHand::getLineCode,user.getLineCode())
                    .eq(SwStTicketHand::getStationCode,user.getStationCode())
                    .eq(SwStTicketHand::getNoticeStatus,"1")
                    .eq(SwStTicketHand::getDelFlag,"0")
                    .orderByDesc(SwStTicketHand::getHandTime);
            records = swStTicketHandService.list(wrapper);
        }
        for (SwStTicketHand record : records) {
            if("0".equals(record.getDataSource())){
                record.setDataSource("线路");
            }else if("1".equals(record.getDataSource())){
                record.setDataSource("车站");
            }
            if("0".equals(record.getSubmitStatus())){
                record.setSubmitStatus("待提交");
            }else if("1".equals(record.getSubmitStatus())){
                record.setSubmitStatus("已提交");
            }
            if("0".equals(record.getHandStatus())){
                record.setHandStatus("待确认");
            }else if("1".equals(record.getHandStatus())){
                record.setHandStatus("已确认");
            }else if("2".equals(record.getHandStatus())){
                record.setHandStatus("差异反馈");
            }else if("3".equals(record.getHandStatus())){
                record.setHandStatus("差异申诉");
            }
        }
        records.forEach(i -> {
            SwStTicketHandDvo dto = new SwStTicketHandDvo();
            BeanUtils.copyProperties(i, dto);
            list.add(dto);
        });
        //List<SwStTicketHand> swStTicketHandList = swStTicketHandService.list(Wrappers.query(swStTicketHand));
        String fileName = URLEncoder.encode("车票上交", "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + System.currentTimeMillis() + ".xlsx");
        EasyExcel.write(response.getOutputStream(), SwStTicketHandDvo.class).registerConverter(new LocalDateTimeConverter())
                .registerConverter(new LocalDateConverter()).sheet("车票上交").doWrite(list);
    }

    @ApiOperation(value = "导出车票回收信息", notes = "导出车票回收信息")
    @GetMapping("/line/export")
    @SysLog("导出车票回收信息")
    //@PreAuthorize("@pms.hasPermission('stm_sw_st_ticket_hand_export')")
    public void exportLineExcel(@RequestParam(value = "ids") List<Integer> ids, HttpServletResponse response) throws IOException {
        List<SwStTicketHandRecoveryDvo> list = new ArrayList<>();
        List<SwStTicketHand> swStTicketHandList;
        PigxUser user = SecurityUtils.getUser();
        Map<String,String> params = new HashMap<>();
        params.put("lineCode",user.getLineCode());
        params.put("stationCode",user.getStationCode());
        swStTicketHandList = swStTicketHandMapper.queryExport(ids,params);
        R<List<SysDictItem>> inputDataStatus = systemUserService.getDictByType(StmConstans.SW_ST_TICKET_HAND_STATUS);
        List<SysDictItem> dictData = inputDataStatus.getData();
        for (SwStTicketHand record : swStTicketHandList) {
            Map<String, String> map = dictData.stream().collect(Collectors.toMap(SysDictItem::getValue, SysDictItem::getLabel));
            record.setHandStatus(map.get(record.getHandStatus()));
            if("0".equals(record.getDataSource())){
                record.setDataSource("线路");
            }else if("1".equals(record.getDataSource())){
                record.setDataSource("车站");
            }else if("2".equals(record.getDataSource())){
                record.setDataSource("临时配收计划");
            }
            if("0".equals(record.getNoticeStatus())){
                record.setNoticeStatus("未通知");
            }else if("1".equals(record.getNoticeStatus())){
                record.setNoticeStatus("已通知");
            }
            if("0".equals(record.getIsInstock())){
                record.setIsInstock("否");
            }else if("1".equals(record.getIsInstock())){
                record.setIsInstock("是");
            }
            if("0".equals(record.getIsOutstock())){
                record.setIsOutstock("否");
            }else if("1".equals(record.getIsOutstock())){
                record.setIsOutstock("是");
            }
        }
        swStTicketHandList.forEach(i -> {
            SwStTicketHandRecoveryDvo dto = new SwStTicketHandRecoveryDvo();
            BeanUtils.copyProperties(i, dto);
            list.add(dto);
        });
        //List<SwStTicketHand> swStTicketHandList = swStTicketHandService.list(Wrappers.query(swStTicketHand));
        String fileName = URLEncoder.encode("车票回收", "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + System.currentTimeMillis() + ".xlsx");
        EasyExcel.write(response.getOutputStream(), SwStTicketHandRecoveryDvo.class).registerConverter(new LocalDateTimeConverter())
                .registerConverter(new LocalDateConverter()).sheet("车票回收").doWrite(list);
    }
    /**
     * 车票回收信息模板下载
     * @param
     * @return
     * @throws
     */
    @ApiOperation(value = "车票回收信息模板下载", notes = "车票回收信息模板下载")
    @GetMapping("/exportTamplateRecovery")
    public void exportTamplateRecovery(HttpServletResponse response) {
        swStTicketHandService.exportTamplateRecovery(response);
    }
    /**
     * 车票回收信息导入
     *
     * @param file
     * @return
     */
    @ApiOperation(value = "车票回收信息导入", notes = "车票回收信息导入")
    @SysLog("车票回收信息导入")
    @PostMapping({ "/ImportRecycle" })
    @Transactional(rollbackFor = Exception.class)
    public R ImportRecycle(@RequestParam("file") final MultipartFile file) throws Exception {

        final File excelFile = MultipartFileToFile.multipartFileToFile(file);
        List<Map<Integer, String>> listMap = EasyExcel.read(file.getInputStream()).sheet().headRowNumber(2).doReadSync();
        if (CollectionUtil.isNotEmpty(listMap)) {
            MultipartFileToFile.delteTempFile(excelFile);
            List<SwStTicketHandAndDetailExcelDvo> excelDvoList = new ArrayList<>();//处理数据表
            List<SwStTicketHandDetail> swStTicketHandDetailList = new ArrayList<>();//回收明细表

			List<SysDictItem> dcpTicketReturnItems = systemUserService.typeOrderBy("TICKET_RETURN_TYPE").getData();

            for (int m = 0; m < listMap.size(); m++) {
                Map<Integer, String> data = listMap.get(m);
                // 返回每条数据的键值对 key表示所在的列位置 value表示所在列的值
                LOGGER.info("读取到数据:{}", JSON.toJSONString(data));
                SwStTicketHandAndDetailExcelDvo excelDvo = new SwStTicketHandAndDetailExcelDvo();
                if(ObjectUtil.isEmpty(data.get(0))){
                    return R.failed("导入失败，请检查【线路】后重新导入！");
                }else {
                    SwParamLine swParamLine = swParamLineMapper.selectOne(Wrappers.<SwParamLine>lambdaQuery().eq(SwParamLine::getName, data.get(0)));
                    if(ObjectUtil.isEmpty(swParamLine)){
                        return R.failed("导入失败，请检查【线路】后重新导入！");
                    }
                    excelDvo.setLineCode(swParamLine.getCode());//线路
                }

                if(ObjectUtil.isEmpty(data.get(1))){
                    return R.failed("导入失败，请检查【站点】后重新导入！");
                }else {
                    SwParamStation swParamStation = swParamStationMapper.selectOne(Wrappers.<SwParamStation>lambdaQuery()
                            .eq(SwParamStation::getLineCode, excelDvo.getLineCode()).eq(SwParamStation::getName, data.get(1)));
                    if(ObjectUtil.isEmpty(swParamStation)){
                        return R.failed("导入失败，请检查【站点】后重新导入！");
                    }
                    excelDvo.setStationCode(swParamStation.getCode());//站点
                }

                if(ObjectUtil.isEmpty(data.get(7))){
                    return R.failed("导入失败，请检查【票种】后重新导入！");
                }else {
                    SwPmTicketCardType swPmTicketCardType = swPmTicketCardTypeService.getOne(Wrappers.<SwPmTicketCardType>lambdaQuery().eq(SwPmTicketCardType::getMainName, data.get(7)));
                    if(ObjectUtil.isEmpty(swPmTicketCardType)){
                        return R.failed("导入失败，请检查【票种】后重新导入！");
                    }
                    excelDvo.setTicketType(getStringData(swPmTicketCardType.getMainEnName()));//票种
                }

                if(ObjectUtil.isEmpty(data.get(8))){
                    return R.failed("导入失败，请检查【车票名称】后重新导入！");
                }else {
                    SwPmTicketCardTypeParam swPmTicketCardTypeParam = swPmTicketCardTypeParamService.getOne(Wrappers.<SwPmTicketCardTypeParam>lambdaQuery()
                            .eq(SwPmTicketCardTypeParam::getSubName,data.get(8)));
                    if(ObjectUtil.isEmpty(swPmTicketCardTypeParam)){
                        return R.failed("导入失败，请检查【车票名称】后重新导入！");
                    }
                    excelDvo.setTicketName(getStringData(swPmTicketCardTypeParam.getSubEnName()));//车票名称
                }
				//20250109增加车票种类的导入 在车票名称后面，属于第9个，后面代码9之后的加1 
				if(ObjectUtil.isEmpty(data.get(9))){
                    return R.failed("导入失败，请检查【车票种类】后重新导入！");
                }else {
                  
					for (SysDictItem dictItem : dcpTicketReturnItems) {
						String name  = dictItem.getLabel();
						String value = dictItem.getValue();
						if(data.get(9).equals(name)){							
                           excelDvo.setTicketReturnType(value);//车票种类
						   break;
						}                        
                     }
					 if(ObjectUtil.isEmpty(excelDvo.getTicketReturnType())){
						  return R.failed("导入失败，请检查【车票种类】后重新导入！");
						
					 }	
                   
                }

                if(ObjectUtil.isEmpty(data.get(6))){
                    return R.failed("导入失败，请检查【时间格式】后重新导入！");
                }else {
                    boolean date = DateUtilStm.isDate(data.get(6), "yyyy-MM-dd HH:mm:ss");//检查时间格式
                    if(!date){
                        return R.failed("导入失败，请检查【时间格式】后重新导入！");
                    }
                    excelDvo.setReceiveTime(data.get(6));//回收时间
                }

                excelDvo.setReceivePersonName(getStringData(data.get(2)));//回收人1
                excelDvo.setReceivePersonCode(getStringData(data.get(3)));//回收人工号1
                excelDvo.setReceivePersonTwoName(getStringData(data.get(4)));//回收人2
                excelDvo.setReceivePersonTwoCode(getStringData(data.get(5)));//回收人工号2
                /* 20250109 前面增加一列后，后面顺序调整
                excelDvo.setNumberInterval(getStringData(data.get(9)));//号段
                excelDvo.setCardNumber(getStringData(data.get(10)));//卡号
                excelDvo.setTicketAmount(getData(data.get(11)));//金额
                excelDvo.setTicketCount(getStringData(data.get(12)));//次数
                excelDvo.setReceiveCount(data.get(13) == null ? 0 : Integer.valueOf(data.get(13)));//回收数量
                excelDvo.setRemark(getStringData(data.get(14)));//备注
                */
				excelDvo.setNumberInterval(getStringData(data.get(10)));//号段
                excelDvo.setCardNumber(getStringData(data.get(11)));//卡号
                excelDvo.setTicketAmount(getData(data.get(12)));//金额
                excelDvo.setTicketCount(getStringData(data.get(13)));//次数
                excelDvo.setReceiveCount(data.get(14) == null ? 0 : Integer.valueOf(data.get(14)));//回收数量
                excelDvo.setRemark(getStringData(data.get(15)));//备注
				excelDvoList.add(excelDvo);

            }
            // 分组统计回收车票
            Map<String,List<SwStTicketHandAndDetailExcelDvo>> countMap = excelDvoList.stream().collect(Collectors
                    .groupingBy(o -> o.getLineCode() + "_" + o.getStationCode()
                            + "_" + o.getReceivePersonCode() + "_" + o.getReceivePersonName()
                            + "_" + o.getReceivePersonTwoCode() + "_" + o.getReceivePersonTwoName()
                            + "_" +o.getReceiveTime(), Collectors.toList()));
            if(countMap.isEmpty()){
                return R.failed("导入失败，请检查数据后重新导入！");
            }
            Set<String> keySet = countMap.keySet();
            PigxUser user = SecurityUtils.getUser();
            for (String key : keySet) {
                List<SwStTicketHandAndDetailExcelDvo> dvos = countMap.get(key);
                String[] temp = key.split("_");
                String lineCode = temp[0];
                String stationCode = temp[1];
                String deliveryPersonCode = temp[2];
                String deliveryPersonName = temp[3];
                String deliveryPersonTwoCode = temp[4];
                String deliveryPersonTwoName = temp[5];
                String deliveryTime = temp[6];
                SwStTicketHand swStTicketHand = new SwStTicketHand();//回收主表
                swStTicketHand.setLineCode(lineCode);
                swStTicketHand.setStationCode(stationCode);
                swStTicketHand.setReceivePersonCode(deliveryPersonCode);
                swStTicketHand.setReceivePersonName(deliveryPersonName);
                swStTicketHand.setReceivePersonTwoCode(deliveryPersonTwoCode);
                swStTicketHand.setReceivePersonTwoName(deliveryPersonTwoName);
                swStTicketHand.setReceiveTime(DateUtilStm.LocalDateTimeToString(deliveryTime));
                List<SwStTicketHand> one = swStTicketHandService.list(Wrappers.query(swStTicketHand));
                swStTicketHand.setDataSource("0");//线网添加
                //线网添加的车票回收信息，数据默认同步，车站无需提交，此处默认添加数据就是已提交状态
                swStTicketHand.setSubmitStatus(CommonConstants.SUBMIT);
                //线网添加的车票回收信息，默认通知状态置成未通知且未确认
                swStTicketHand.setNoticeStatus(CommonConstants.UN_INFORMED);
                swStTicketHand.setNoticeConfirm(CommonConstants.UN_CONFIRM);
                swStTicketHand.setHandStatus(CommonConstants.UN_CONFIRM);
                int sum = dvos.stream().mapToInt(SwStTicketHandAndDetailExcelDvo::getReceiveCount).sum();
                swStTicketHand.setReceiveCount(sum);//回收数量
                swStTicketHand.setDelFlag("0");
                swStTicketHand.setDeptId(user.getDeptId());
                swStTicketHand.setCreatorId(user.getId());
                swStTicketHand.setCreatorName(user.getNikeName());//导入人
                swStTicketHand.setCreateTime(LocalDateTime.now());
                if(CollectionUtils.isEmpty(one)){
                    SwStTicketHand swStTicketHandObj = new SwStTicketHand();//回收主表
                    swStTicketHandObj.setLineCode(lineCode);
                    swStTicketHandObj.setStationCode(stationCode);
                    swStTicketHandService.getBaseMapper().insert(swStTicketHand);
                    swStTicketHandObj.setId(swStTicketHand.getId());
                    swStTicketHandService.updateById(swStTicketHandObj);// TODO 处理线路站点存不进去
                    dvos.forEach(x -> {
                        SwStTicketHandDetail swStTicketHandDetail = new SwStTicketHandDetail();//回收明细表
                        BeanUtils.copyProperties(x,swStTicketHandDetail);
                        swStTicketHandDetail.setRefId(swStTicketHand.getId());//主表关联id
                        swStTicketHandDetail.setDelFlag("0");
                        swStTicketHandDetailList.add(swStTicketHandDetail);
                    });
                }else {
                    continue;
                }
            }
            if(CollectionUtil.isNotEmpty(swStTicketHandDetailList)){
                swStTicketHandDetailService.saveBatch(swStTicketHandDetailList);
            }
        }
        return R.ok();
    }

    /**
     *
     * @param ids
     * @param swStTicketHand
     * @return
     */
    @ApiOperation(value = "驳回", notes = "驳回")
    @PostMapping("rejectData")
    public R rejectData( String ids, SwStTicketHand swStTicketHand){
        //驳回：车站
        //条件：数据来源车站、通知状态已通知的、
        //修改状态：把上交状态改为未提交，车票回收状态改为未确认
        List<SwStTicketHand> listByIds = swStTicketHandService.getBaseMapper().selectBatchIds((Arrays.asList(ids.split(","))));
        for (SwStTicketHand byId : listByIds) {
            byId.setRejectReply(swStTicketHand.getRejectReply());//驳回原因
            byId.setSubmitStatus("0");//待提交
            byId.setHandStatus("0");//回收状态待确认
        }
        return R.ok(swStTicketHandService.updateBatchById(listByIds));
    }
    private BigDecimal getData(String money){
        try {
            BigDecimal itemMoney = new BigDecimal(money).setScale(2, BigDecimal.ROUND_HALF_UP);
            return itemMoney;
        } catch (Exception e) {
            return new  BigDecimal("0.00");
        }

    }
    private String getStringData(String param){
        if(ObjectUtil.isEmpty(param)){
            return "";
        }
        return param;
    }


    @PutMapping("/recallConfirm/{id}")
    @SysLog("撤回确认")
    public R outputDetailSubmit(@PathVariable Integer id) {
        SwStTicketHand swStTicketHand = new SwStTicketHand();
        swStTicketHand.setId(id);
        swStTicketHand.setHandStatus("0");
        return R.ok(swStTicketHandService.updateById(swStTicketHand));
    }
}
